package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

@Autowired
   private DishFlavorService dishFlavorService;

@Autowired//接口可以实现任意实现类对象,当我们在某个类加上了Spring的事务管理
private CategoryService categoryService;



    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加菜品
     * @param disDto
     */
    @Override
    public void saveDishAndFlavors(DishDto disDto) {
        //1.添加菜品的基本信息
        save(disDto);
        //2.添加菜品对应的口味信息
        //获取其中口味信息的数据
        List<DishFlavor> flavors = disDto.getFlavors();
        //添加之前将对应的菜品设置进去(告知当前口味属于哪一道菜)
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(disDto.getId());
        }
        //添加多个
    dishFlavorService.saveBatch(flavors);

        //清理某个分类下面的菜品缓存数据
        String key = "dish*";
        redisTemplate.delete(key);
    }

    /**
     * 菜品管理分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public IPage<DishDto> getPage(Integer page, Integer pageSize, String name) {
        //创建分页数据，用于储存除菜品分类的数据
        IPage<Dish> p=new Page<>(page,pageSize);
        //构造条件查询对象
        LambdaQueryWrapper<Dish> qw=new LambdaQueryWrapper();
        //数据模糊查询 name不为空则进行查询，为空就不查询
        qw.like(StringUtils.isNotBlank(name),Dish::getName,name);
        //排序查询,根据修改时间为条件
        qw.orderByDesc(Dish::getUpdateTime);
        page(p,qw);
//========================================================
        //  构造一个新的分页对象
        IPage<DishDto> dtoPage=new Page<>();
        //将p的分页属性复制给dtoPage，但records不需要
        BeanUtils.copyProperties(p,dtoPage," records");
        //获取小苹果的箱子->获得p分页查询到的数据
        List<Dish>dishList= p.getRecords();
        List<DishDto> DishDtoList =dishList.stream().map(dish -> {
            //dish表示获取的每一箱苹果
            // 创建一个DishDto，用于储存原数据dish，和添加新数据菜品分类
            DishDto dishDto=new DishDto();
            //将小箱子的苹果搬到大箱子中->将原数据dish，储存到dishDto
            BeanUtils.copyProperties(dish,dishDto);
            //买柚子
            //select*from category where  category.id=dish.category_id;
            //在根据dish里面的getCategoryId对分类表进行查询
            Category category = categoryService.getById(dish.getCategoryId());
            //将买的柚子也放入大箱子中->吧分类名添加到dishDto里面去
            dishDto.setCategoryName(category.getName());
            //把DishDto类型返回
            return dishDto;
            //装车->以List集合进行收集
        }).collect(Collectors.toList());
        //将收集的到的信息存到新的分类对象去
        dtoPage.setRecords(DishDtoList);
        //将新的分页数据返回
        return dtoPage;
    }


    /**
     * 根据id查询菜品信息和对应的口味信息(回显数据)
     * @param id
     * @return
     */
    @Override
    public DishDto DishAndFlavor(Long id) {
        //查询菜品基本信息
        Dish dish = getById(id);
        //查询对应的口味信息
    //select*from dish_flavor where dish_id=xxx;
    LambdaQueryWrapper<DishFlavor> qw=new LambdaQueryWrapper<>();
    //dish的id和口味的flavorId一致
        qw.eq(DishFlavor::getDishId,id);
        //将查询的口味信息结果设置到集合里
        List<DishFlavor> flavors = dishFlavorService.list(qw);
        //创建dishDto对象
        DishDto  dishDto=new DishDto();
        //设置属性 将菜品基本信息和对应的口味信息设置到dishDto对象中
        BeanUtils.copyProperties(dish,dishDto);
        dishDto.setFlavors(flavors);
        //返回封装好的数据
        return dishDto;
    }

    /**
     * 修改菜品
     * @param dishDto
     */
    @Override
    public void updateDishAndFlavor(DishDto dishDto) {
        //1.修改菜品的基本数据
        updateById(dishDto);
        //2.修改口味信息
        //2.1删除之前所有对应的口味
        //select*from dish_Flavor where dish_id=xxx;
        LambdaQueryWrapper<DishFlavor> qw=new LambdaQueryWrapper<>();
        qw.eq(DishFlavor::getDishId,dishDto.getId());
        //将根据条件删除该口味
        dishFlavorService.remove(qw);
        //2.2添加新提交的口味数据
        //获得口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        //修改之前将对应的菜品设置进去(告知当前口味属于哪一道菜)
        for (DishFlavor flavor : flavors) {
            //给dishId进行赋值
            flavor.setDishId(dishDto.getId());
        }
        //删除之后 添加对应的口味
        dishFlavorService.saveBatch(flavors);
    }



    /**
     * 套餐管理中查询指定分类下的所有菜品
     * @param dish
     * @return
     */
    @Override
    public List<DishDto> getDishListByCId(Dish dish) {
        //优化为 :key为 "dish:cid:1234567"
        //1.先查询redis中是否有数据
        ValueOperations opsForValue = redisTemplate.opsForValue();
        String key="dish:cid:" +dish.getCategoryId();
        List<DishDto> data=(List<DishDto>) opsForValue.get(key);
        if (data==null){
        // select * from dish where category_id = xxx and status = 1;
        // 改为:
        // select * from dish inner join dish_flavor on dish.id=dish_flavor.dish_id where category_id = xxx and status = 1;
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        // 设置分类ID的条件
        qw.eq(Dish::getCategoryId, dish.getCategoryId());
        // 设置状态必须是启用状态
        qw.eq(Dish::getStatus, dish.getStatus());
        // 调用自定义SQL执行查询语句
           data = dishMapper.getDishAndFlavorByCId(qw);
           //存储到redis
           redisTemplate.opsForValue().set(key,data);
            System.out.println("=============查询数据库==============");
        }
        System.out.println("=============返回数据==============");
        return data;
    }

}
